﻿using LiteBlog.Common.Components;
using LiteBlog.IoC;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace LiteBlog.Infrastructure
{
    public class CustomActionInvoker : ControllerActionInvoker
    {
        protected override ActionDescriptor FindAction(ControllerContext controllerContext, ControllerDescriptor controllerDescriptor, string actionName)
        {
            // Required if user types an invalid action, not defined within the controller
            return base.FindAction(controllerContext, controllerDescriptor, actionName) ??
                        base.FindAction(controllerContext, controllerDescriptor, "PageNotFound");
        }

        protected override ActionResult InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters)
        {
            // ResolveComponents(controllerContext, actionDescriptor);
            return base.InvokeActionMethod(controllerContext, actionDescriptor, parameters);
        }

        protected override ActionExecutedContext InvokeActionMethodWithFilters(ControllerContext controllerContext, IList<IActionFilter> filters, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters)
        {
            // ResolveComponents(controllerContext, actionDescriptor);
            return base.InvokeActionMethodWithFilters(controllerContext, filters, actionDescriptor, parameters);
        }

        private void ResolveComponents(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
        {
            var resolveAttributes = actionDescriptor.GetCustomAttributes(typeof(ResolveAttribute), false);
            if (resolveAttributes != null && resolveAttributes.Length > 0)
            {
                var controller = controllerContext.Controller;
                var controllerType = controller.GetType();
                foreach (var resolveAttribute in resolveAttributes)
                {
                    var resolveAttributeCasted = (ResolveAttribute)resolveAttribute;
                    // Use a bit of reflection here to resolve the property name
                    var propertyInfo = controllerType.GetProperty(resolveAttributeCasted.PropertyName);
                    var propertyValue = IoCContainer.Resolve(propertyInfo.PropertyType);
                    propertyInfo.SetValue(controller, propertyValue, null);
                }
            }
        }
    }
}